package cn.tedu.charging.device.service;

import cn.tedu.charging.common.pojo.po.ChargingGunInfoPO;
import cn.tedu.charging.common.pojo.po.ChargingStationPO;
import cn.tedu.charging.common.pojo.query.NearStationsQuery;
import cn.tedu.charging.common.pojo.vo.GunInfoVO;
import cn.tedu.charging.common.pojo.vo.StationDetailVO;
import cn.tedu.charging.common.pojo.vo.StationInfoVO;
import cn.tedu.charging.device.mapper.StationMapper;
import cn.tedu.charging.device.repository.DeviceRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.domain.geo.GeoLocation;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DeviceServiceImpl implements DeviceService{
    @Autowired
    private DeviceRepository deviceRepository;
    //仓储层数据 读写来自数据库 数据库持久层对象po
    //仓储层数据 读写来自缓存 缓存持久层对象po TODO
    //仓储层数据 读写查询搜索来自es es搜索应请索引的持久层po TODO
    @Override
    public List<StationInfoVO> nearStations(NearStationsQuery query) {
        //1.读取缓存geo数据 得到List<GeoResult<GeoLocation<Integer>> TODO
        List<GeoResult> geoRes = deviceRepository.nearStations(query);
        //2.判断命中,如果不为空,解析
        List<StationInfoVO> vos=null;
        //3.循环遍历数组集合 用元素值 查询stationPO缓存，封装转化vo
        if (geoRes!=null&&geoRes.size()>0){
            vos=new ArrayList<>();
            for (GeoResult<GeoLocation<Integer>> geo : geoRes) {
                //1.distance 返回单位千米 多个小数点 取2位 四舍五入
                double value = geo.getDistance().getValue();//没有对小数点处理
                Double distance=new BigDecimal(value).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
                //2.point x=lng y=lat
                Double lng=geo.getContent().getPoint().getX();
                Double lat=geo.getContent().getPoint().getY();
                //3.member=stationId
                Integer stationId=geo.getContent().getName();
                //4.stationName=另一个缓存string获取po封装 TODO
                String stationName = deviceRepository.getStationName(stationId);
                //5.准备vo 填补属性,
                StationInfoVO vo=new StationInfoVO();
                vo.setDistance(distance);
                vo.setStationLat(new BigDecimal(lat));
                vo.setStationLng(new BigDecimal(lng));
                vo.setStationName(stationName);
                vo.setStationId(stationId);
                vos.add(vo);
            }
        }
        return vos;
    }

    @Override
    public StationDetailVO detailStation(Integer stationId) {
        //1.stationPO 从缓存 stationName address
        ChargingStationPO stationPO = deviceRepository.getStationById(stationId);
        if (stationPO==null){
            return null;
        }
        //2.查询该场站下的所有枪
        List<ChargingGunInfoPO> gunPos = deviceRepository.getGunListByStationId(stationId);
        //3.利用查询的数据封装vo 其中gunList list.stream()api
        StationDetailVO vo=new StationDetailVO();
        vo.setStationName(stationPO.getStationName());
        vo.setAddress(stationPO.getAddress());
        //场站下的枪 将gunPos转化成gunVos 使用增强for循环没问题,这里选择使用映射
        List<GunInfoVO> gunVos = gunPos.stream().map(gunPO -> {
            //如何将集合元素 进行映射转化
            GunInfoVO gunVO = new GunInfoVO();
            BeanUtils.copyProperties(gunPO, gunVO);
            return gunVO;
        }).collect(Collectors.toList());
        vo.setGunInfoPOList(gunVos);
        return vo;
    }

    @Override
    public Object updateGunStatus(Integer gunId, Integer status) {
        return null;
    }
}
